package com.pm.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yitter.idgen.YitIdHelper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.pm.common.constant.ProjectConstants;
import com.pm.common.core.domain.AjaxResult;
import com.pm.common.core.domain.TreeSelect;
import com.pm.common.core.domain.entity.*;
import com.pm.common.core.domain.model.LoginUser;
import com.pm.common.enums.DelFlagEnum;
import com.pm.common.enums.SystemStatusEnum;
import com.pm.common.utils.ProjectUtils;
import com.pm.common.utils.SecurityUtils;
import com.pm.common.utils.StringUtils;
import com.pm.project.domain.vo.ProjectTempleteDefineVO;
import com.pm.project.domain.vo.ProjectTempleteVersionVO;
import com.pm.project.mapper.ProjectListNodeMapper;
import com.pm.project.mapper.ProjectTempleteDefineMapper;
import com.pm.project.mapper.ProjectTempleteVersionMapper;
import com.pm.project.service.ProjectTempleteService;
import com.pm.system.mapper.SysDictDataMapper;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

@Service
public class ProjectTempleteServiceImpl implements ProjectTempleteService {


    @Resource
    SysDictDataMapper sysDictDataMapper;

    @Resource
    ProjectTempleteDefineMapper projectTempleteDefineMapper;

    @Resource
    ProjectTempleteVersionMapper projectTempleteVersionMapper;

    @Resource
    RedisTemplate redisTemplate;


    @Resource
    RedisLockRegistry redisLockRegistry;





    @Override
    @Transactional
    public AjaxResult prepareAdd(ProjectTempleteVersion projectTempleteVersion) {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        //设置ID
        projectTempleteVersion.setId(YitIdHelper.nextId());
        //默认设置是非当前版本
        projectTempleteVersion.setStatus(SystemStatusEnum.CANCEL.getStatus().toString());
        //预插入 状态为失效 提交时才将状态设置成有效
        projectTempleteVersion.setDelFlag(DelFlagEnum.CANCEL.getStatus());
        projectTempleteVersion.setCreateBy(loginUser.getUserId());
        projectTempleteVersionMapper.insert(projectTempleteVersion);

        //获取配置的初始项目
        SysDictData sysDictData = new SysDictData();
        sysDictData.setDictType("project_templete_node");
        List<SysDictData> list = sysDictDataMapper.selectDictDataList(sysDictData);

        //批量插入模板定义表
        if(!CollectionUtils.isEmpty(list)){
            for (SysDictData dictData : list) {
                ProjectTempleteDefine projectTempleteDefine = new ProjectTempleteDefine();
                projectTempleteDefine.setNodeName(dictData.getDictValue());
                projectTempleteDefine.setParentId(projectTempleteVersion.getId());
                projectTempleteDefine.setVersionId(projectTempleteVersion.getId());
                projectTempleteDefine.setStatus(SystemStatusEnum.OK.getStatus());
                projectTempleteDefine.setCreateBy(loginUser.getUserId());
                projectTempleteDefineMapper.insert(projectTempleteDefine);
            }
        }

        return AjaxResult.success(projectTempleteVersion.getId());
    }

    /**
     * 添加节点
     * @param projectTempleteDefine
     * @return
     */
    @Override
    @Transactional
    public AjaxResult addNode(ProjectTempleteDefine projectTempleteDefine) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        projectTempleteDefine.setCreateBy(loginUser.getUserId());
        projectTempleteDefineMapper.insert(projectTempleteDefine);

        //添加节点岗位关联表
        projectTempleteDefineMapper.addDefineMember(projectTempleteDefine);
        return AjaxResult.success("操作成功!");
    }


    /**
     * 查询模板列表
     * @param projectTempleteVersion
     * @return
     */
    @Override
    public List<ProjectTempleteVersionVO> list(ProjectTempleteVersion projectTempleteVersion) {

        MPJLambdaWrapper<ProjectTempleteVersion> query = JoinWrappers.lambda(ProjectTempleteVersion.class);
        query.leftJoin(SysUser.class,"s",SysUser::getUserId,ProjectTempleteVersion::getCreateBy)
                .eq(ProjectTempleteVersion::getDelFlag,0)//未删除的数据
                .selectAs(SysUser::getNickName, ProjectTempleteVersionVO::getNickName)
                .selectAll(ProjectTempleteVersion.class);
//                .selectAs(ProjectTempleteVersion::getId, ProjectTempleteVersionVO::getId)
//                .selectAs(ProjectTempleteVersion::getVersionNo, ProjectTempleteVersionVO::getVersionNo)
//                .selectAs(ProjectTempleteVersion::getStatus, ProjectTempleteVersionVO::getStatus)
//                .selectAs(ProjectTempleteVersion::getCreateTime, ProjectTempleteVersionVO::getCreateTime) ;
        if(StringUtils.isNotBlank(projectTempleteVersion.getVersionNo())){
            query.eq(ProjectTempleteVersion::getVersionNo,projectTempleteVersion.getVersionNo());
        }

        if(StringUtils.isNotBlank(projectTempleteVersion.getVersionName())){
            query.eq(ProjectTempleteVersion::getVersionName,projectTempleteVersion.getVersionName());
        }


        return projectTempleteVersionMapper.selectJoinList(ProjectTempleteVersionVO.class,query);
    }


    /**
     * 模板新增
     * @param projectTempleteVersion
     * @return
     */
    @Override
    @Transactional
    public AjaxResult add(ProjectTempleteVersion projectTempleteVersion) {


        //设置版本号
        String versionNo = createVersionNo();


        LoginUser loginUser = SecurityUtils.getLoginUser();
        //设置添加时间
        projectTempleteVersion.setCreateBy(loginUser.getUserId());
        projectTempleteVersion.setCreateTime(new Date());
        //设置成未删除
        projectTempleteVersion.setDelFlag(DelFlagEnum.OK.getStatus());

        //版本号
        projectTempleteVersion.setVersionNo(versionNo);

        //如果设置成当前版本 则先失效其他版本
        if(Integer.valueOf(projectTempleteVersion.getStatus()) == SystemStatusEnum.OK.getStatus()){
            ProjectTempleteVersion update = new ProjectTempleteVersion();
            update.setStatus(SystemStatusEnum.CANCEL.getStatus().toString());
            update.setUpdateTime(new Date());
            update.setUpdateBy(loginUser.getUserId());
            QueryWrapper<ProjectTempleteVersion> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("del_flag",0);
            projectTempleteVersionMapper.update(update,queryWrapper);
        }


        //更新状态
        projectTempleteVersionMapper.updateById(projectTempleteVersion);

        //缓存版本号
        redisTemplate.opsForValue().set(ProjectConstants.PROJECT_TEMPLETE_VERSION_KEY,versionNo);

        return AjaxResult.success("操作成功!");
    }

    /**
     * 创建版本号
     * @return
     */
    private String createVersionNo() {
        String lockKey = "projectTempleteLockKey" ;

        String versionNo = "";

        Lock lock = redisLockRegistry.obtain(lockKey);

        try{
            lock.lock();

            QueryWrapper<ProjectTempleteVersion> queryWrapper = new QueryWrapper<>();
            queryWrapper.orderByDesc("version_no").isNotNull("version_no");
            //查询最大的版本号
            List<ProjectTempleteVersion> list = projectTempleteVersionMapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(list)){
                versionNo   =  ProjectConstants.ONE+".0";
            }else{
                BigDecimal version = BigDecimal.valueOf(Double.valueOf(list.get(0).getVersionNo())).add(BigDecimal.valueOf(0.1));

                versionNo = String.valueOf(version);
            }


        }catch (Exception e){
            e.printStackTrace();

        }finally {
            lock.unlock();
        }

        return versionNo;

    }

    /**
     * 查询模板详情
     * @param projectTempleteVersion
     * @return
     */
    @Override
    public ProjectTempleteVersion detail(ProjectTempleteVersion projectTempleteVersion) {

        ProjectTempleteVersion detail = projectTempleteVersionMapper.selectById(projectTempleteVersion.getId());

        //查询所有节点
        List<ProjectTempleteDefine> list = projectTempleteDefineMapper.queryProjectTempleteDefine(projectTempleteVersion);


        List<ProjectTempleteDefine>  treeList = ProjectUtils.buildProjectTempleteDefineTree(list);
        detail.setProjectTempleteDefineList(treeList);
        List<TreeSelect> ts = treeList.stream().map(TreeSelect::new).collect(Collectors.toList());
        detail.setTreeSelectList(ts);
        return detail;
    }

    /**
     * 更新节点名称
     * @param projectTempleteDefine
     * @return
     */
    @Override
    public AjaxResult updateNode(ProjectTempleteDefine projectTempleteDefine) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        ProjectTempleteDefine update = new ProjectTempleteDefine();
        update.setId(projectTempleteDefine.getId());
        update.setNodeName(projectTempleteDefine.getNodeName());
        update.setNeedFlag(projectTempleteDefine.getNeedFlag());
        update.setUpdateTime(new Date());
        update.setUpdateBy(loginUser.getUserId());
        projectTempleteDefineMapper.updateById(projectTempleteDefine);
        return AjaxResult.success("修改成功!");
    }

    @Override
    @Transactional
    public AjaxResult copy(ProjectTempleteVersion projectTempleteVersion) {

        //主表
        ProjectTempleteVersion detail = projectTempleteVersionMapper.selectById(projectTempleteVersion);
        detail.setId(null);
        detail.setDelFlag(DelFlagEnum.CANCEL.getStatus());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        detail.setCreateBy(loginUser.getUserId());
        projectTempleteVersionMapper.insert(detail);

        //明细表
        QueryWrapper<ProjectTempleteDefine> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("version_id",projectTempleteVersion.getId());
        List<ProjectTempleteDefine> list = projectTempleteDefineMapper.selectList(queryWrapper);

        if(!CollectionUtils.isEmpty(list)){
            for (ProjectTempleteDefine projectTempleteDefine : list) {
                projectTempleteDefine.setVersionId(detail.getId());
                //替换之前项目的跟节点ID
                if(projectTempleteDefine.getParentId().longValue() == projectTempleteVersion.getId().longValue()){
                    projectTempleteDefine.setParentId(detail.getId());
                }
                projectTempleteDefineMapper.insert(projectTempleteDefine);
            }
        }

        return AjaxResult.success(detail.getId());
    }

    /**
     * 设置成当前版本
     * @param id
     * @return
     */
    @Override
    @Transactional
    public AjaxResult updateStatus(String id) {

        LoginUser sysUser = SecurityUtils.getLoginUser();
        //将其余版本全部设置成非当前版本
        ProjectTempleteVersion update = new ProjectTempleteVersion();
        update.setStatus(SystemStatusEnum.CANCEL.getStatus().toString());
        update.setUpdateTime(new Date());
        update.setUpdateBy(sysUser.getUserId());
        QueryWrapper<ProjectTempleteVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag",0);
        projectTempleteVersionMapper.update(update,queryWrapper);

        //设置当前版本号
        update.setId(Long.valueOf(id));
        update.setStatus(SystemStatusEnum.OK.getStatus().toString());
        projectTempleteVersionMapper.updateById(update);


        return AjaxResult.success("操作成功!");
    }

    /**
     * 查询当前模板详情
     * @param projectTempleteVersion
     * @return
     */
    @Override
    public ProjectTempleteVersion currTemDetail(ProjectTempleteVersion projectTempleteVersion) {
        QueryWrapper<ProjectTempleteVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("del_flag","0");
        queryWrapper.eq("status","0");
        ProjectTempleteVersion currProjectTempleteVersion = projectTempleteVersionMapper.selectOne(queryWrapper);
        ProjectTempleteVersion res = detail(currProjectTempleteVersion);
        List<String> list = new ArrayList<>();

        if(res != null && !CollectionUtils.isEmpty(res.getProjectTempleteDefineList())){
            for (ProjectTempleteDefine projectTempleteDefine : res.getProjectTempleteDefineList()) {
                createCheckedByRes(projectTempleteDefine,list);
            }
            res.setCheckedList(list);
        }



        return res;
    }


   private void createCheckedByRes(ProjectTempleteDefine projectTempleteDefine,List<String> list ){
            if(!CollectionUtils.isEmpty(projectTempleteDefine.getChildren())){
                for (ProjectTempleteDefine child : projectTempleteDefine.getChildren()) {
                    createCheckedByRes(child,list);
                }
            }else{
                if(projectTempleteDefine.getNeedFlag() != null && projectTempleteDefine.getNeedFlag() == 0){
                    list.add(projectTempleteDefine.getId().toString());
                }
            }
    }

    /**
     * 删除节点
     * @param projectTempleteDefine
     * @return
     */
    @Override
    public AjaxResult delNode(ProjectTempleteDefine projectTempleteDefine) {

        projectTempleteDefineMapper.deleteById(projectTempleteDefine.getId());

        return AjaxResult.success("操作成功!");
    }


}
